package io.renren.modules.yckj.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.renren.common.page.PageData;
import io.renren.common.service.impl.CrudServiceImpl;
import io.renren.common.utils.ConvertUtils;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.Result;
import io.renren.common.utils.SmsUtil;
import io.renren.modules.yckj.common.wx.WeChatProperties;
import io.renren.modules.yckj.dao.*;
import io.renren.modules.yckj.dto.*;
import io.renren.modules.yckj.entity.CouponsLogsEntity;
import io.renren.modules.yckj.entity.InvoiceLogsEntity;
import io.renren.modules.yckj.entity.OrderEntity;
import io.renren.modules.yckj.entity.TeamRelationEntity;
import io.renren.modules.yckj.enums.status.CommonStatus;
import io.renren.modules.yckj.enums.status.OrderStatus;
import io.renren.modules.yckj.enums.status.TeamAppointStatus;
import io.renren.modules.yckj.enums.status.TeamStatus;
import io.renren.modules.yckj.enums.type.AmountType;
import io.renren.modules.yckj.enums.type.AssetType;
import io.renren.modules.yckj.enums.type.BusinessType;
import io.renren.modules.yckj.enums.type.PayWay;
import io.renren.modules.yckj.service.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 预约列表
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2025-04-25
 */
@Service
@AllArgsConstructor
public class OrderServiceImpl extends CrudServiceImpl<OrderDao, OrderEntity, OrderDTO> implements OrderService {
    private final UserDao userDao;
    private final TeamDao teamDao;
    private final TeamRelationDao teamRelationDao;
    private final InvoiceLogsDao invoiceLogsDao;

    private final UserService userService;
    private final AssetLogService assetLogService;
    private final TeamService teamService;
    private final TeamRelationService teamRelationService;
    private final MachineService machineService;
    private final ProjectService projectService;
    private final ProjectMachineService projectMachineService;
    private final CouponsLogsService couponsLogsService;
    private final WeChatProperties weChatProperties;

    @Override
    public QueryWrapper<OrderEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");
        Object status = params.get("status");
        Object teamId = params.get("teamId");
        Object teamReview = params.get("teamReview");
        String projectName = (String) params.get("projectName");
        String userName = (String) params.get("userName");

        Object machineId = params.get("machineId");
        String machineName = (String) params.get("machineName");
        Object machineType = params.get("machineType");

        Object leStatus = params.get("leStatus");
        String mulStatus = (String) params.get("mulStatus");

        Object startTime = params.get("startTime");
        Object endTime = params.get("endTime");

        Object bkId = params.get("bkId");
        String bkName = (String) params.get("bkName");
        Object bkIdNotNull = params.get("bkIdNotNull");


        QueryWrapper<OrderEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
        wrapper.eq(ObjectUtil.isAllNotEmpty(status), "status", status);
        wrapper.eq(ObjectUtil.isAllNotEmpty(teamId), "team_id", teamId);
        wrapper.eq(ObjectUtil.isAllNotEmpty(teamReview), "team_review", teamReview);
        wrapper.like(StrUtil.isNotBlank(projectName), "project_name", projectName);
        wrapper.like(StrUtil.isNotBlank(userName), "user_name", userName);

        wrapper.eq(ObjectUtil.isAllNotEmpty(machineId), "machine_id", machineId);
        wrapper.like(StrUtil.isNotBlank(machineName), "machine_name", machineName);
        wrapper.eq(ObjectUtil.isAllNotEmpty(machineType), "machine_type", machineType);

        wrapper.le(ObjectUtil.isAllNotEmpty(leStatus), "status", leStatus);
        if (StrUtil.isNotBlank(mulStatus)) {
            wrapper.in("status", Arrays.stream(mulStatus.split(",")).collect(Collectors.toList()));
        }

        wrapper.ge(ObjectUtil.isAllNotEmpty(startTime), "book_time", startTime);
        wrapper.le(ObjectUtil.isAllNotEmpty(endTime), "book_time", endTime);
        wrapper.eq(ObjectUtil.isAllNotEmpty(bkId), "bk_id", bkId);
        wrapper.like(StrUtil.isNotBlank(bkName), "bk_name", bkName);
        wrapper.ge(ObjectUtil.isAllNotEmpty(bkIdNotNull) && bkIdNotNull.equals(true), "bk_id", 0);

        return wrapper;
    }

    @Override
    public PageData<OrderDTO> pageForAdmin(Map<String, Object> params) {
        //分页
        IPage<OrderEntity> page = getPage(params, "id", false);
        //查询
        List<OrderEntity> list = baseDao.pageForAdmin(params);
        return getPageData(list, page.getTotal(), OrderDTO.class);
    }

    @Override
    public BigDecimal sumActualAmount(Map<String, Object> params) {
        List<OrderEntity> entityList = baseDao.selectList(getWrapper(params));
        return entityList.stream().map(OrderEntity::getActualAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }


    @Override
    public BigDecimal sumBookTotalTime(Map<String, Object> params) {
        List<OrderEntity> entityList = baseDao.selectList(getWrapper(params));
        return entityList.stream().map(OrderEntity::getBookTotalTime)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    @Override
    public List<OrderDTO> getOrderList(Map<String, Object> params) {
        List<OrderEntity> entityList = baseDao.getOrderList(params);
        return ConvertUtils.sourceToTarget(entityList, OrderDTO.class);
    }

    @Override
    public PageData<OrderDTO> pageForApi(Map<String, Object> params) {
        //分页
        IPage<OrderEntity> page = getPage(params, "id", false);
        //查询
        List<OrderEntity> list = baseDao.getOrderList(params);
        return getPageData(list, page.getTotal(), OrderDTO.class);
    }

    @Override
    public Result<Boolean> validatorAppoint(OrderDTO orderDTO) throws Exception {
        orderDTO.setBookTime(new Date());
        if (orderDTO.getMachineId() != null) {
            MachineDTO machineDTO = machineService.get(orderDTO.getMachineId());
            if (machineDTO != null && machineDTO.getStatus().equals(CommonStatus.YES.getCode())) {
                orderDTO.setMachineName(machineDTO.getName());
                orderDTO.setMachineType(machineDTO.getType());
            } else {
                return new Result<Boolean>().error("当前机器维修！");
            }
        }
        if (orderDTO.getProjectId() != null) {
            ProjectDTO projectDTO = projectService.get(orderDTO.getProjectId());
            if (projectDTO != null && projectDTO.getStatus().equals(CommonStatus.YES.getCode())) {
                orderDTO.setProjectName(projectDTO.getName());
            } else {
                return new Result<Boolean>().error("当前项目已下线！");
            }
        }
        //计算预约的实际价格
        Map<String, Object> map = new HashMap<>();
        map.put("projectId", orderDTO.getProjectId());
        map.put("machineId", orderDTO.getMachineId());
        Optional<ProjectMachineDTO> projectMachineDTO = projectMachineService.list(map).stream().findAny();
        if (projectMachineDTO.isPresent()) {
            BigDecimal machineAmount = projectMachineDTO.get().getPrice().multiply(orderDTO.getBookTotalTime());
            orderDTO.setActualAmount(machineAmount);
            if (orderDTO.getAppendixOnePrice() != null && orderDTO.getAppendixOneNum() != null) {
                BigDecimal appendixAmount = orderDTO.getAppendixOnePrice().multiply(orderDTO.getAppendixOneNum());
                orderDTO.setActualAmount(machineAmount.add(appendixAmount));
            }
        } else {
            return new Result<Boolean>().error("当前项目机器关系有误！");
        }
        if (orderDTO.getCouponsLogId() != null) {
            //校验优惠券是否可用
            CouponsLogsDTO couponsLogsDTO = couponsLogsService.get(orderDTO.getCouponsLogId());
            if (couponsLogsDTO != null) {
                if (couponsLogsDTO.getStatus().equals(CommonStatus.YES.getCode())) {
                    return new Result<Boolean>().error("优惠券已使用！");
                } else {
                    if (couponsLogsDTO.getDeadlineTime().before(new Date())) {
                        return new Result<Boolean>().error("优惠券已过期！");
                    } else {
                        orderDTO.setCouponsId(couponsLogsDTO.getCouponsId());
                        orderDTO.setCouponsTitle(couponsLogsDTO.getTitle());
                        orderDTO.setCouponsDiscount(couponsLogsDTO.getDiscount());
                        if (couponsLogsDTO.getDiscount().compareTo(orderDTO.getActualAmount()) > 0) {
                            orderDTO.setActualAmount(BigDecimal.ZERO);
                        } else {
                            orderDTO.setActualAmount(orderDTO.getActualAmount().subtract(couponsLogsDTO.getDiscount()));
                        }
                    }
                }
            } else {
                return new Result<Boolean>().error("优惠券不存在！");
            }
        }
        //选组按组结算
        if (orderDTO.getTeamId() != null && orderDTO.getTeamId() > 0) {
            TeamDTO teamDTO = teamService.get(orderDTO.getTeamId());
            if (teamDTO != null && teamDTO.getStatus().equals(TeamStatus.YES.getCode())) {
                orderDTO.setTeamName(teamDTO.getName());
                orderDTO.setPayWay(PayWay.TEAM.getCode());
                Map<String, BigDecimal> availableBalance = userService.getAvailableBalance(orderDTO.getUserId(), teamDTO.getId());
                if (availableBalance.get("team").compareTo(orderDTO.getActualAmount()) < 0) {
                    return new Result<Boolean>().error("当前组额度不足！");
                }
            } else {
                return new Result<Boolean>().error("当前组无效！");
            }
        } else {
            Map<String, BigDecimal> availableBalance = userService.getAvailableBalance(orderDTO.getUserId(), null);
            orderDTO.setPayWay(PayWay.USER.getCode());
            if (availableBalance.get("user").compareTo(orderDTO.getActualAmount()) < 0) {
                return new Result<Boolean>().error("当前用户额度不足！");
            }
        }
        //预约日期排序
        if (orderDTO.getBookAllTimes() != null && !orderDTO.getBookAllTimes().isEmpty()) {
            List<Date> dates = new ArrayList<>();
            List<String> sortTimes = new ArrayList<>();
            String[] times = orderDTO.getBookAllTimes().split(",");
            Arrays.stream(times)
                    .forEach(dt -> {
                        Date date = DateUtils.parse(dt, DateUtils.DATE_TIME_PATTERN_16);
                        dates.add(date);
                    });

            // 对日期进行排序
            Collections.sort(dates);
            for (int i = 0; i < dates.size(); i++) {
                Date f = dates.get(i);
                if (i == 0) {
                    orderDTO.setBookTime(f);
                    orderDTO.setBookStartTime(DateUtils.format(f, DateUtils.DATE_TIME_PATTERN));
                }
                if (i == dates.size() - 1) {
                    orderDTO.setBookEndTime(DateUtils.format(f, DateUtils.DATE_TIME_PATTERN));
                }
                sortTimes.add(DateUtils.format(f, DateUtils.DATE_TIME_PATTERN_16));
            }
            orderDTO.setBookAllTimes(String.join(",", sortTimes));
        }
        boolean appointBool = appoint(orderDTO);
        if (appointBool) {
            try {
//                //发送模板消息
//                String json = userService.getTagUsers();
//                JSONObject jsonObject = new JSONObject(json);
//                JSONArray openIds = jsonObject.getJSONObject("data").getJSONArray("openid");
//                for (Object openId : openIds) {
//                    String msg = userService.sendTemplateMsg(openId.toString(), orderDTO.getMachineName(), orderDTO.getBookStartTime(), orderDTO.getBookEndTime(), orderDTO.getProjectName(), orderDTO.getPhone());
//                    System.out.printf("msg:%s\n", msg);
//                }
                String time = DateUtils.format(orderDTO.getBookTime(), DateUtils.DATE_PATTERN);
                if (orderDTO.getBookStartTime() != null) {
                    Date temp = DateUtils.parse(orderDTO.getBookStartTime(), DateUtils.DATE_TIME_PATTERN);
                    time = time + " " + DateUtils.format(temp, DateUtils.TIME_PATTERN_4);
                }
                if (orderDTO.getBookEndTime() != null) {
                    Date temp = DateUtils.parse(orderDTO.getBookEndTime(), DateUtils.DATE_TIME_PATTERN);
                    Date lastDate = new Date(temp.getTime() + 30 * 60 * 1000);
                    time = time + " " + DateUtils.format(lastDate, DateUtils.TIME_PATTERN_4);
                }
                SmsUtil.batchSendSmsToAdmin(weChatProperties.getPhones(), orderDTO.getProjectName(), orderDTO.getContacts(), time);
            } catch (Exception e) {
                System.out.printf("msg error:%s", e.getMessage());
            }
        }
        return new Result<Boolean>().ok(appointBool);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean appoint(OrderDTO orderDTO) throws Exception {
        //保存订单
        boolean b = this.save(orderDTO);
        if (!b)
            throw new Exception("保存预约失败");
        //更新优惠券状态
        if (orderDTO.getCouponsLogId() != null) {
            CouponsLogsEntity couponsLogsEntity = new CouponsLogsEntity();
            couponsLogsEntity.setId(orderDTO.getCouponsLogId());
            couponsLogsEntity.setStatus(CommonStatus.YES.getCode());
            b = couponsLogsService.updateById(couponsLogsEntity);
            if (!b)
                throw new Exception("更新优惠券状态失败");
        }

        //预约时 使用额度增加
        BigDecimal debtLimitUse = orderDTO.getActualAmount();
        if (orderDTO.getPayWay().equals(PayWay.USER.getCode())) {
            //更新个人使用用额度
            b = userDao.updateDebtLimitUse(orderDTO.getUserId(), debtLimitUse);
            if (!b)
                throw new Exception("更新用户限额失败");
        } else if (orderDTO.getPayWay().equals(PayWay.TEAM.getCode())) {
            //更新组内个人及组使用额度
            TeamRelationEntity teamRelation = teamRelationService.getByTeamIdAndUserId(orderDTO.getTeamId(), orderDTO.getUserId());
            if (teamRelation != null) {
                if (teamRelation.getAmountPower().equals(AmountType.FIXED.getCode())
                        || teamRelation.getAmountPower().equals(AmountType.ALL.getCode())) {
                    b = teamRelationDao.updateDebtLimitUse(teamRelation.getId(), debtLimitUse);
                    if (!b)
                        throw new Exception("更新组内用户限额失败");
                    b = teamDao.updateDebtLimitUse(orderDTO.getTeamId(), debtLimitUse);
                    if (!b)
                        throw new Exception("更新组限额失败");
                }
            }
        }
        return b;
    }

    /**
     * 组预约订单审核
     *
     * @param orderDTO     订单表
     * @param status       组审核状态
     * @param teamRelation 关系
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean teamApprove(OrderDTO orderDTO, Integer status, TeamRelationEntity teamRelation) throws Exception {
        boolean b;
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setId(orderDTO.getId());
        orderEntity.setTeamReview(status);
        if (status.equals(TeamAppointStatus.REFUSED.getCode())) {
            orderEntity.setStatus(OrderStatus.REFUSED.getCode());
            BigDecimal amount = orderDTO.getActualAmount().multiply(new BigDecimal(-1));
            b = teamRelationDao.updateDebtLimitUse(teamRelation.getId(), amount);
            if (!b)
                throw new Exception("更新组用户限额失败");
            b = teamDao.updateDebtLimitUse(teamRelation.getTeamId(), amount);
            if (!b)
                throw new Exception("更新组限额失败");
            //更新优惠券状态，退还优惠券
            if (orderDTO.getCouponsLogId() != null) {
                CouponsLogsEntity couponsLogsEntity = new CouponsLogsEntity();
                couponsLogsEntity.setId(orderDTO.getCouponsLogId());
                couponsLogsEntity.setStatus(CommonStatus.NO.getCode());
                b = couponsLogsService.updateById(couponsLogsEntity);
                if (!b)
                    throw new Exception("更新优惠券状态失败");
            }
        }
        b = this.updateById(orderEntity);
        if (!b)
            throw new Exception("更新订单数据失败");
        return b;
    }

    /**
     * 更新订单真实金额
     *
     * @param orderDTO     订单表
     * @param actualAmount 修改的金额
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAmount(OrderDTO orderDTO, BigDecimal actualAmount) throws Exception {
        //保存订单
        OrderEntity update = new OrderEntity();
        update.setId(orderDTO.getId());
        update.setActualAmount(actualAmount);
        update.setUpdateTime(new Date());
        boolean b = this.updateById(update);
        if (!b)
            throw new Exception("更新订单数据失败");
        //更新 使用额度增加
        BigDecimal debtLimitUse = actualAmount.subtract(orderDTO.getActualAmount());
        if (orderDTO.getPayWay().equals(PayWay.USER.getCode())) {
            //更新个人使用用额度
            b = userDao.updateDebtLimitUse(orderDTO.getUserId(), debtLimitUse);
            if (!b)
                throw new Exception("更新用户限额失败");
        } else if (orderDTO.getPayWay().equals(PayWay.TEAM.getCode())) {
            //更新组内个人及组使用额度
            TeamRelationEntity teamRelation = teamRelationService.getByTeamIdAndUserId(orderDTO.getTeamId(), orderDTO.getUserId());
            if (teamRelation != null) {
                if (teamRelation.getAmountPower().equals(AmountType.FIXED.getCode())
                        || teamRelation.getAmountPower().equals(AmountType.ALL.getCode())) {
                    b = teamRelationDao.updateDebtLimitUse(teamRelation.getId(), debtLimitUse);
                    if (!b)
                        throw new Exception("更新用户组内限额失败");
                    b = teamDao.updateDebtLimitUse(orderDTO.getTeamId(), debtLimitUse);
                    if (!b)
                        throw new Exception("更新组限额失败");
                }
            }
        }
        return b;
    }

    /**
     * 所有预约订单
     *
     * @param orderDTO 订单表
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancel(OrderDTO orderDTO) throws Exception {
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setId(orderDTO.getId());
        orderEntity.setStatus(OrderStatus.CANCEL.getCode());
        boolean b = this.updateById(orderEntity);
        if (!b)
            throw new Exception("更新订单数据失败");
        //更新优惠券状态，退还优惠券
        if (orderDTO.getCouponsLogId() != null) {
            CouponsLogsEntity couponsLogsEntity = new CouponsLogsEntity();
            couponsLogsEntity.setId(orderDTO.getCouponsLogId());
            couponsLogsEntity.setStatus(CommonStatus.NO.getCode());
            b = couponsLogsService.updateById(couponsLogsEntity);
            if (!b)
                throw new Exception("更新优惠券状态失败");
        }
        //取消时 使用额度减少
        BigDecimal debtLimitUse = orderDTO.getActualAmount().multiply(new BigDecimal(-1));
        if (orderDTO.getPayWay().equals(PayWay.USER.getCode())) {
            //更新个人欠款
            b = userDao.updateDebtLimitUse(orderDTO.getUserId(), debtLimitUse);
            if (!b)
                throw new Exception("更新用户限额失败");
        } else if (orderDTO.getPayWay().equals(PayWay.TEAM.getCode())) {
            //更新组内个人及组使用额度
            TeamRelationEntity teamRelation = teamRelationService.getByTeamIdAndUserId(orderDTO.getTeamId(), orderDTO.getUserId());
            if (teamRelation != null) {
                if (teamRelation.getAmountPower().equals(AmountType.FIXED.getCode())
                        || teamRelation.getAmountPower().equals(AmountType.ALL.getCode())) {
                    b = teamRelationDao.updateDebtLimitUse(teamRelation.getId(), debtLimitUse);
                    if (!b)
                        throw new Exception("更新用户组内限额失败");
                    b = teamDao.updateDebtLimitUse(teamRelation.getTeamId(), debtLimitUse);
                    if (!b)
                        throw new Exception("更新组限额失败");
                }
            }
        }
        return b;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean balancePayByUser(Long userId, OrderDTO orderDTO) throws Exception {
        //个人支付 更新订单状态
        boolean b = updateOrderPayStatus(orderDTO);
        if (!b)
            throw new Exception("更新订单状态失败");
        //更新用户余额+限额
        BigDecimal balance = orderDTO.getActualAmount().multiply(new BigDecimal(-1));
        BigDecimal debtLimitUse = orderDTO.getActualAmount().multiply(new BigDecimal(-1));
        b = userDao.updateBalanceAndDebtLimitUse(userId, balance, debtLimitUse);
        if (!b)
            throw new Exception("更新用户余额状态失败");
        //保存日志
        b = saveAssetLog(orderDTO);
        if (!b)
            throw new Exception("保存用户资产记录失败");
        return b;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean balancePayByUserByAdmin(Long userId, OrderDTO orderDTO) throws Exception {
        //个人支付 更新订单状态
        boolean b = updateOrderPayStatus(orderDTO);
        if (!b)
            throw new Exception("更新订单状态失败");
        //更新用户限额
        BigDecimal debtLimitUse = orderDTO.getActualAmount().multiply(new BigDecimal(-1));
        b = userDao.updateDebtLimitUse(userId, debtLimitUse);
        if (!b)
            throw new Exception("更新用户限额状态失败");
        //保存日志
        b = saveAssetLog(orderDTO);
        if (!b)
            throw new Exception("保存用户资产记录失败");
        return b;
    }

    /**
     * //组订单
     *
     * @param userId   用户id
     * @param orderDTO 订单
     * @return boolean
     * @throws Exception 异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean balancePayByUserForTeam(Long userId, OrderDTO orderDTO) throws Exception {
        //更新订单状态
        boolean b = updateOrderPayStatus(orderDTO);
        if (!b)
            throw new Exception("更新订单状态失败");
        //更新用户余额
        BigDecimal balance = orderDTO.getActualAmount().multiply(new BigDecimal(-1));
        b = userDao.updateBalance(userId, balance);
        if (!b) {
            throw new Exception("更新用户余额状态失败");
        }
        //更新组限额
        BigDecimal debtLimitUse = orderDTO.getActualAmount().multiply(new BigDecimal(-1));
        b = teamDao.updateDebtLimitUse(orderDTO.getTeamId(), debtLimitUse);
        if (!b)
            throw new Exception("更新组限额失败");
        //更新组内个人限额
        TeamRelationEntity teamRelation = teamRelationService.getByTeamIdAndUserId(orderDTO.getTeamId(), orderDTO.getUserId());
        if (teamRelation != null) {
            if (teamRelation.getAmountPower().equals(AmountType.FIXED.getCode())
                    || teamRelation.getAmountPower().equals(AmountType.ALL.getCode())) {
                b = teamRelationDao.updateDebtLimitUse(teamRelation.getId(), debtLimitUse);
                if (!b)
                    throw new Exception("更新用户限额失败");
            }
        } else {
            throw new Exception("当前用户不在当前组内");
        }
        //保存日志
        b = saveAssetLog(orderDTO);
        if (!b)
            throw new Exception("保存用户资产记录失败");
        return b;
    }

    /**
     * 组订单 后台更新
     *
     * @param userId   用户id
     * @param orderDTO 订单
     * @return boolean
     * @throws Exception 异常
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean balancePayByUserForTeamByAdmin(Long userId, OrderDTO orderDTO) throws Exception {
        //更新订单状态
        boolean b = updateOrderPayStatus(orderDTO);
        if (!b)
            throw new Exception("更新订单状态失败");
        //更新组限额
        BigDecimal debtLimitUse = orderDTO.getActualAmount().multiply(new BigDecimal(-1));
        b = teamDao.updateDebtLimitUse(orderDTO.getTeamId(), debtLimitUse);
        if (!b)
            throw new Exception("更新组限额失败");
        //更新组内个人限额
        TeamRelationEntity teamRelation = teamRelationService.getByTeamIdAndUserId(orderDTO.getTeamId(), orderDTO.getUserId());
        if (teamRelation != null) {
            if (teamRelation.getAmountPower().equals(AmountType.FIXED.getCode())
                    || teamRelation.getAmountPower().equals(AmountType.ALL.getCode())) {
                b = teamRelationDao.updateDebtLimitUse(teamRelation.getId(), debtLimitUse);
                if (!b)
                    throw new Exception("更新用户限额失败");
            }
        } else {
            throw new Exception("当前用户不在当前组内");
        }
        //保存日志
        b = saveAssetLog(orderDTO);
        if (!b)
            throw new Exception("保存用户资产记录失败");
        return b;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean balancePayByTeam(Long teamId, OrderDTO dto) throws Exception {
        //组支付 更新订单状态
        boolean b = updateOrderPayStatus(dto);
        if (!b)
            throw new Exception("更新订单状态失败");
        //更新组余额+限额
        BigDecimal balance = dto.getActualAmount().multiply(new BigDecimal(-1));
        BigDecimal debtLimitUse = dto.getActualAmount().multiply(new BigDecimal(-1));
        b = teamDao.updateBalanceAndDebtLimitUse(teamId, balance, debtLimitUse);
        if (!b)
            throw new Exception("更新级余额状态失败");
        //保存日志
        b = saveAssetLog(dto);
        if (!b)
            throw new Exception("保存用户资产记录失败");
        return b;
    }

    /**
     * 所有预约订单
     *
     * @param orderDTO 订单表
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean applyInvoice(OrderDTO orderDTO, InvoiceLogsDTO invoiceLogsDTO) throws Exception {
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setId(orderDTO.getId());
        orderEntity.setIsInvoice(CommonStatus.YES.getCode());
        orderEntity.setInvoiceId(invoiceLogsDTO.getInvoiceId());
        boolean b = this.updateById(orderEntity);
        if (!b)
            throw new Exception("更新订单数据失败");
        InvoiceLogsEntity invoiceLogsEntity = new InvoiceLogsEntity();
        invoiceLogsEntity.setId(invoiceLogsDTO.getId());
        invoiceLogsEntity.setInvoiceId(invoiceLogsDTO.getInvoiceId());
        invoiceLogsEntity.setInvoiceType(invoiceLogsDTO.getInvoiceType());
        invoiceLogsEntity.setFileType(invoiceLogsDTO.getFileType());
        invoiceLogsEntity.setNote(invoiceLogsDTO.getNote());
        b = invoiceLogsDao.updateById(invoiceLogsEntity) > 0;
        if (!b)
            throw new Exception("更新发票数据失败");
        return b;
    }


    private boolean updateOrderPayStatus(OrderDTO orderDTO) {
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setId(orderDTO.getId());
        orderEntity.setPayWay(orderDTO.getPayWay());
        orderEntity.setStatus(OrderStatus.FINISHED.getCode());
        orderEntity.setFinishType(orderDTO.getFinishType());
        return this.updateById(orderEntity);
    }

    private boolean saveAssetLog(OrderDTO orderDTO) {
        AssetLogDTO assetLogDTO = new AssetLogDTO();
        assetLogDTO.setUserId(orderDTO.getUserId());
        assetLogDTO.setUsername(orderDTO.getUserName());
        assetLogDTO.setAmount(orderDTO.getActualAmount());
        assetLogDTO.setType(AssetType.PAY.getCode());
        assetLogDTO.setBusinessType(BusinessType.PAY_ORDER.getCode());
        assetLogDTO.setNote(BusinessType.PAY_ORDER.getName());
        assetLogDTO.setCreateTime(new Date());
        assetLogDTO.setUpdateTime(new Date());
        //保存日志
        return assetLogService.save(assetLogDTO);
    }


}